package org.richin.servlet.util;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class ResponseUtils {
	 /** HTTP Accept-Charset Header for internal requests used during static export. */
    public static final String HEADER_ACCEPT_CHARSET = "Accept-Charset";

    /** HTTP Accept-Language Header for internal requests used during static export. */
    public static final String HEADER_ACCEPT_LANGUAGE = "Accept-Language";

    /** HTTP Header "Cache-Control". */
    public static final String HEADER_CACHE_CONTROL = "Cache-Control";

    /** The "Content-Disposition" http header. */
    public static final String HEADER_CONTENT_DISPOSITION = "Content-Disposition";

    /** The "Content-Type" http header. */
    public static final String HEADER_CONTENT_TYPE = "Content-Type";

    /** HTTP Header "Expires". */
    public static final String HEADER_EXPIRES = "Expires";

    /** HTTP Header "If-Modified-Since". */
    public static final String HEADER_IF_MODIFIED_SINCE = "If-Modified-Since";

    /** The Header that stores the session id (used by OpenCms upload applet). */
    public static final String HEADER_JSESSIONID = "JSESSIONID";

    /** HTTP Header "Last-Modified". */
    public static final String HEADER_LAST_MODIFIED = "Last-Modified";

    /** HTTP Header for internal requests used during static export. */
    public static final String HEADER_OPENCMS_EXPORT = "OpenCms-Export";

    /** HTTP Header "Pragma". */
    public static final String HEADER_PRAGMA = "Pragma";

    /** HTTP Header "Server". */
    public static final String HEADER_SERVER = "Server";

    /** HTTP Header "user-agent". */
    public static final String HEADER_USER_AGENT = "user-agent";

    /** HTTP Header value "max-age=" (for "Cache-Control"). */
    public static final String HEADER_VALUE_MAX_AGE = "max-age=";

    /** HTTP Header value "must-revalidate" (for "Cache-Control"). */
    public static final String HEADER_VALUE_MUST_REVALIDATE = "must-revalidate";

    /** HTTP Header value "no-cache" (for "Cache-Control"). */
    public static final String HEADER_VALUE_NO_CACHE = "no-cache";

    /** HTTP Header "WWW-Authenticate". */
    public static final String HEADER_WWW_AUTHENTICATE = "WWW-Authenticate";

    /** Identifier for x-forwarded-for (i.e. proxied) request headers. */
    public static final String HEADER_X_FORWARDED_FOR = "x-forwarded-for";
	private static final Log log = LogFactory.getLog(ResponseUtils.class);
	public static void preventCaching(HttpServletResponse response)
	{
		response.addHeader(HEADER_CACHE_CONTROL,"no-cache");			// HTTP/1.1
		response.addHeader(HEADER_CACHE_CONTROL,"no-store");			// HTTP/1.1
		response.addHeader(HEADER_CACHE_CONTROL,"must-revalidate");	// HTTP/1.1
		response.addHeader("Pragma","no-cache");             	// HTTP 1.0
		response.addHeader("Expires", "1");
	}

	/**
     * Gzipping an empty file or stream always results in a 20 byte output
     * This is in java or elsewhere.
     * <p/>
     * On a unix system to reproduce do <code>gzip -n empty_file</code>. -n tells gzip to not
     * include the file name. The resulting file size is 20 bytes.
     * <p/>
     * Therefore 20 bytes can be used indicate that the gzip byte[] will be empty when ungzipped.
     */
    private static final int EMPTY_GZIPPED_CONTENT_SIZE = 20;

    /**
     * Utility class. No public constructor.
     */
    private  ResponseUtils() {
		// TODO Auto-generated constructor stub
	}


    /**
     * Checks whether a gzipped body is actually empty and should just be zero.
     * When the compressedBytes is {@link #EMPTY_GZIPPED_CONTENT_SIZE} it should be zero.
     *
     * @param compressedBytes the gzipped response body
     * @param request         the client HTTP request
     * @return true if the response should be 0, even if it is isn't.
     */
    public static boolean shouldGzippedBodyBeZero(byte[] compressedBytes, HttpServletRequest request) {

        //Check for 0 length body
        if (compressedBytes.length == EMPTY_GZIPPED_CONTENT_SIZE) {
        	log.debug(request.getRequestURL() + " resulted in an empty response.");
           
            return true;
        } else {
            return false;
        }
    }


    /**
     * Performs a number of checks to ensure response saneness according to the rules of RFC2616:
     * <ol>
     * <li>If the response code is {@link javax.servlet.http.HttpServletResponse#SC_NO_CONTENT} then it is illegal for the body
     * to contain anything. See http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.5
     * <li>If the response code is {@link javax.servlet.http.HttpServletResponse#SC_NOT_MODIFIED} then it is illegal for the body
     * to contain anything. See http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.5
     * </ol>
     *
     * @param request         the client HTTP request
     * @param responseStatus         the responseStatus
     * @return true if the response should be 0, even if it is isn't.
     */
    public static boolean shouldBodyBeZero(HttpServletRequest request, int responseStatus) {

        //Check for NO_CONTENT
        if (responseStatus == HttpServletResponse.SC_NO_CONTENT) {
            	log.debug(request.getRequestURL() + " resulted in a " + HttpServletResponse.SC_NO_CONTENT
                        + " response. Removing message body in accordance with RFC2616.");
            
            return true;
        }

        //Check for NOT_MODIFIED
        if (responseStatus == HttpServletResponse.SC_NOT_MODIFIED) {
        	log.debug(request.getRequestURL() + " resulted in a " + HttpServletResponse.SC_NOT_MODIFIED
                        + " response. Removing message body in accordance with RFC2616.");
            
            return true;
        }

        return false;
    }

    /**
     * Adds the gzip HTTP header to the response. This is need when a gzipped body is returned so that browsers can properly decompress it.
     * <p/>
     * @param response the response which will have a header added to it. I.e this method changes its parameter
     * @throws ResponseHeadersNotModifiableException Either the response is committed or we were called using the include method
     * from a {@link javax.servlet.RequestDispatcher#include(javax.servlet.ServletRequest, javax.servlet.ServletResponse)}
     * method and the set set header is ignored.
     */
    public static void addGzipHeader(final HttpServletResponse response) throws ServletException {
        response.setHeader("Content-Encoding", "gzip");
        boolean containsEncoding = response.containsHeader("Content-Encoding");
        if (!containsEncoding) {
            throw new ServletException("Failure when attempting to set "
                    + "Content-Encoding: gzip");
        }
    }
    /**
     * Set the response "Expires" and "Cache-Control" headers with the given
     * maximum cache duration age in seconds.
     *
     * @param response the response to set the headers in
     * @param maxAgeSeconds the maximum cache duration in seconds
     */
    protected void setHeaderExpiresCache(HttpServletResponse response, long maxAgeSeconds) {
        long expiresMs = System.currentTimeMillis() + (maxAgeSeconds * 1000);
        response.setDateHeader("Expires", expiresMs);
        response.setHeader("Cache-Control", "max-age=" + maxAgeSeconds);
    }

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
HttpServletResponse response=null;

	}

}
